package com.shawn.server.Advice;

import com.alibaba.fastjson.JSON;
import com.shawn.commons.utils.RC;
import com.shawn.server.annotation.ExpressionEvaluator;
import com.shawn.server.annotation.LogConfig;
import com.shawn.server.interceptor.ThreadContext;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.context.expression.AnnotatedElementKey;
import org.springframework.expression.EvaluationContext;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author shawn
 * @date 2022年 12月 15日 10:56
 */
//@Component
//@Aspect
public class LogAdvice {
    @Resource
    private AmqpTemplate amqpTemplate;

    @Before(value = "execution(* com.shawn.server.service.*.*(..))&& @annotation(config)")
    public void sendLogMessage(JoinPoint pjp , LogConfig config){
        String objId = parse(pjp);
        try {
            Map map = new HashMap<>();
            map.put("userId", ThreadContext.getUserId());
            map.put("type",config.type().getType());
            map.put("busId",objId);
            map.put("logTime",new SimpleDateFormat(RC.GENERAL_DATE_FORMAT).format(new Date()));
            String message = JSON.toJSONString(map);
            amqpTemplate.convertAndSend("touch.log.exchange","log."+config.key(),message);
        } catch (AmqpException e) {
            e.printStackTrace();
        }
    }

    private String parse(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();

        Object[] args = joinPoint.getArgs();
        if(args.length>0){//说明有参数
            LogConfig logConfig = method.getAnnotation(LogConfig.class);
            ExpressionEvaluator<String> evaluator = new ExpressionEvaluator<>();
            EvaluationContext evaluationContext = evaluator.createEvaluationContext(joinPoint.getTarget(), joinPoint.getTarget().getClass(), ((MethodSignature) joinPoint.getSignature()).getMethod(), joinPoint.getArgs());
            AnnotatedElementKey methodKey = new AnnotatedElementKey(((MethodSignature) joinPoint.getSignature()).getMethod(), joinPoint.getTarget().getClass());
            return evaluator.condition(logConfig.objId(), methodKey, evaluationContext, String.class);
        }
        return null;
    }
}



